package com.ihai.spring.boot.sample.ehcache.controller;

import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.Configuration;
import net.sf.ehcache.config.FactoryConfiguration;
import net.sf.ehcache.config.MemoryUnit;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * DESC
 *
 * @author 张驰
 * @date 2019/12/16
 */
@RestController
public class EhcacheController {
    private Ehcache ehcache;
    @Value("${ehcache.port}")
    private String ehcachePort;

    public EhcacheController() {
        Configuration configuration = new Configuration();
        CacheConfiguration cacheConfiguration = new CacheConfiguration();
        cacheConfiguration.name("testCache");
        cacheConfiguration.maxBytesLocalHeap(100, MemoryUnit.MEGABYTES);
        configuration.addCache(cacheConfiguration);
        CacheManager manager = CacheManager.create(configuration);
        ehcache = manager.getCache("testCache");
        ehcache.put(new Element("count", new AtomicInteger(0)));
    }

    @RequestMapping("/incr")
    public Object incr() {
        long start = System.currentTimeMillis();
        ehcache.acquireWriteLockOnKey("count");
        Element element = ehcache.get("count");
        ehcache.getWriterManager().dispose();
        int count = ((AtomicInteger) element.getObjectValue()).incrementAndGet();
        ehcache.put(element);
        ehcache.releaseWriteLockOnKey("count");
        System.out.println(System.currentTimeMillis() - start);
        return count;
    }

    @RequestMapping("/1add3")
    public void add(@RequestParam String port) {
        Element ele = ehcache.get("count");
        ehcache.getCacheManager().shutdown();
        Configuration configuration = new Configuration();
        CacheConfiguration cacheConfiguration = new CacheConfiguration();
        cacheConfiguration.name("testCache");
        cacheConfiguration.maxBytesLocalHeap(100, MemoryUnit.MEGABYTES);
        CacheConfiguration.CacheEventListenerFactoryConfiguration cacheEventListenerFactoryConfiguration = new CacheConfiguration.CacheEventListenerFactoryConfiguration();
        cacheEventListenerFactoryConfiguration.className("net.sf.ehcache.distribution.RMICacheReplicatorFactory")
                .properties("replicateAsynchronously=false, replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true");
        cacheConfiguration.addCacheEventListenerFactory(cacheEventListenerFactoryConfiguration);
        configuration.addCache(cacheConfiguration);
        FactoryConfiguration providerFactoryConfiguration = new FactoryConfiguration();
        providerFactoryConfiguration.className("net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory")
                .properties("peerDiscovery=manual,rmiUrls=//192.168.16.114:" + port + "/testCache");
        configuration.addCacheManagerPeerProviderFactory(providerFactoryConfiguration);
        FactoryConfiguration listenerFactoryConfiguration = new FactoryConfiguration();
        listenerFactoryConfiguration.className("net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory")
                .properties("hostName=0.0.0.0, port=" + ehcachePort + ", socketTimeoutMillis=2000");
        configuration.addCacheManagerPeerListenerFactory(listenerFactoryConfiguration);
        configuration.setName("CM" + System.currentTimeMillis());
        CacheManager manager = CacheManager.create(configuration);
        ehcache = manager.getCache("testCache");
        ehcache.put(ele);
//        if(ehcache.get("count") == null){
//            ehcache.put(new Element("count",new AtomicInteger(0)));
//        }
    }
}
